import { AfterViewInit, ChangeDetectionStrategy, Component, OnInit, Pipe, PipeTransform, ViewChild } from '@angular/core';
import { TreeTableNode, TreetableComponent, SortDirective, lvFlattenTreeData } from '@iux/live';
import { map, result, forEach } from 'lodash';
import { startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

@Pipe({ name: 'userProp' })
export class UserPropPipe implements PipeTransform {
  transform(value: TreeTableNode[], exponent: string = 'data.name') {
    return map(value, item => result(item, exponent)).join(',');
  }
}

@Component({
  selector: 'app-async-subnode',
  templateUrl: './async-subnode.component.html',
  styleUrls: [],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AsyncSubnodeComponent implements OnInit, AfterViewInit {
  data: TreeTableNode[];
  selection: TreeTableNode[] = [];
  @ViewChild(TreetableComponent, { static: false }) lvTreeTable: TreetableComponent;
  @ViewChild(SortDirective, { static: false }) lvSort: SortDirective;
  private treeTableDestroy$ = new Subject<void>();

  ngOnInit() {
    this.initData();
  }

  ngAfterViewInit() {
    this.subscribeRenderChange();
  }

  subscribeRenderChange() {
    this.lvTreeTable.renderDataChange$.pipe(startWith(this.lvTreeTable.renderData), takeUntil(this.treeTableDestroy$)).subscribe(() => {
      const flattenData = lvFlattenTreeData(this.lvTreeTable.renderData, null, { getNodeLevel: true }).map(item => item.data);
      this.lvTreeTable.renderData = flattenData;
    });
  }

  initData() {
    this.data = Array.from({ length: 20 }).map((item, index) => ({
      data: {
        key: `uid${index}`,
        id: `uid${index}`,
        name: `user${index}`,
        age: 10,
        expand: false,
        random: 66,
        disabled: false,
        expanded: false,
      },
      children: [],
    }));
  }

  // 默认选中第一个节点及其子节点
  initSelection(source) {
    this.selection.push(source);
    forEach(source.children, item => {
      !item.disabled && this.initSelection(item);
    });
  }

  selectionChange(source) {
    this.lvTreeTable.setSelection();
    console.log('selection change', source, this.selection);
  }

  updateData() {
    this.initData();
    this.lvSort.clear();
  }

  expandedChange(isExpanded, item, rowData) {
    if (!isExpanded) {
      // 解决收起之后平铺数据里面的rowData发生变更
      // rowData的每个item需要变更地址，触发<td>的变更，拿到每个节点最新的子节点
      rowData.forEach((rowItem, index) => {
        rowData[index] = { ...rowItem };
      });
      this.data = [...this.data];
      return;
    }
    item.children = this.initTreeNode(item.data.name.split('-')[0], item._lv_level + 1);
    // rowData的每个item需要变更地址，触发<td>的变更，拿到每个节点最新的子节点
    rowData.forEach((rowItem, index) => {
      rowData[index] = { ...rowItem };
    });
    // data地址需要变更
    this.data = [...this.data];
    this.initChildSelection(item);
    // selection地址需要变更
    this.selection = [...this.selection];
  }

  initTreeNode(key, level, len = 3) {
    return Array.from({ length: len }).map((item, index) => ({
      data: {
        key: `uid${key}${level}${index}`,
        id: `uid${key}${level}${index}`,
        name: `${key}-level-${level}-${index}`,
        age: 10,
        expand: false,
        random: 66,
        disabled: false,
        expanded: false,
      },
      children: level > 3 ? undefined : [],
    }));
  }

  /** 通过父节点的选中状态初始化子节点的选中 */
  private initChildSelection(source) {
    const isSelected = this.selection.some(item => item.data.key === source.data.key);

    if (isSelected) {
      source.children.forEach(item => {
        this.selection.push(item);
      });
    } else {
      this.selection = this.selection.filter(item => item.parent.data.key === source.data.key);
    }
  }

  clearSelection() {
    this.lvTreeTable.clearSelection();
  }

  stateChange(source: { [key: string]: any }) {
    console.log('state change:', source);
  }

  trackByIndex(index) {
    return index;
  }

  ngOnDestroy(): void {
    this.treeTableDestroy$.next();
    this.treeTableDestroy$.complete();
  }
}
